﻿using electrical_machinery.Utils;
using Model;
using MQTTTool.Page;
using Scancodeupload.util;
using SerailDriver;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MQTTTool.MyControls
{
    public partial class LittleGenius : UserControl
    {
        /// <summary>
        /// 扫码枪的全局变量全局只有一个
        /// </summary>
        Saomiao bardCodeHook = new Saomiao();
        public SerailDriverCla serailDriver;
        public List<AutoMsgModel> models = new List<AutoMsgModel>();//自动回发消息的集合
        private SerialPort serialPort;
        //扫码结果
        private string result = "";
        //文件路径
        string filePath = "";
        //文件是否导出过
        public static bool isImport = false;
        //项目下bin下debug的路径
        private string base_path = AppDomain.CurrentDomain.BaseDirectory + "sn\\";
        //文件读取数据
        public LittleGenius()
        {
            InitializeComponent();
            addPort();

            bardCodeHook.ScanerEventNull();
            bardCodeHook.ScanerEvent += Listener_ScanerEvent;
            bardCodeHook.Start();
        }

        /// <summary>
        /// 扫码枪监听事件
        /// </summary>
        /// <param name="codes"></param>
        public void Listener_ScanerEvent(Saomiao.ScanerCodes codes)
        {
            try
            {
                //扫码结果
                result = codes.Result;

                //读取存入的sn码，判断是否有重码
                string sn = readLog();
                if (sn.IndexOf(",") != -1)
                {
                    string[] snArray = sn.Split(',');
                    if (snArray.Contains(result))
                    {
                        Hint hint2 = new Hint("当前这个码["+result+"]已测试过",false);
                        hint2.ShowDialog();
                        return;
                    }
                }
                Thread.Sleep(100);
                //写入sn码
                witeLog(result);
                Hint hint = new Hint("扫码成功：" + result);
                hint.ShowDialog();

            }
            catch (Exception ex)
            {
                // 处理 JSON 反序列化异常
                MessageBox.Show("失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 解析小天才设备串口传过来的数据    渲染数据
        /// </summary>
        /// <param name="input"></param>
        private void queryData(string input)
        {


            string pattern = @"\{(.+?)\}";

            // 使用正则表达式匹配并提取数据
            MatchCollection matches = Regex.Matches(input, pattern);

            // 遍历匹配结果并输出
            List<string> datas = new List<string>();
            datas.Clear();
            foreach (Match match in matches)
            {
                Console.WriteLine(match.Groups[1].Value); // 输出匹配到的内容
                datas.Add(match.Groups[1].Value);

            }

            this?.Invoke(new Action(() =>
            {
                dataGridViewX1.Rows.Clear();
                //格式化数据,项目名称
                for (int i = 3; i < datas.Count; i++)
                {
                    //项目名称
                    label3.Text = datas[i];
                    //{测试结果0不合格1合格}
                    if (datas[i + 1].Equals("1"))
                    {
                        label5.ForeColor = Color.Green;
                        label6.Text = "PASS";
                    }
                    else
                    {
                        label5.ForeColor = Color.Red;
                        label6.Text = "FAIL";
                    }
                    break;
                }
                //格式化数据，表格数据
                List<List<string>> tableDatas = new List<List<string>>();
                //每五个一组
                List<string> tableData = new List<string>();
                for (int i = 6; i < datas.Count; i++)
                {

                    tableData.Add(datas[i]);
                    if (i % 5 == 0)
                    {
                        tableDatas.Add(tableData);
                        tableData = new List<string>();
                    }
                }

                //将数据转换成表格
                //数据格式 ： {项目名称(单位)} {最小值~最大值} {实际值} {测试结果0不合格1合格} {15编号}   
                for (int i = 0; i < tableDatas.Count; i++)
                {

                    //项目名称
                    string name = tableDatas[i][0];
                    //单位
                    string unit = "";
                    //取单位
                    if (tableDatas[i][0].IndexOf("(") != -1 && tableDatas[i][0].IndexOf(")") != -1)
                    {
                        name = tableDatas[i][0].Substring(0, tableDatas[i][0].IndexOf("("));
                        unit = tableDatas[i][0].Substring(tableDatas[i][0].IndexOf("(") + 1, tableDatas[i][0].IndexOf(")") - tableDatas[i][0].IndexOf("(") - 1);
                    }

                    //取大小值
                    string minNumber = "0";
                    string maxNumber = "";
                    if (tableDatas[i][1].IndexOf("~") != -1)
                    {
                        minNumber = tableDatas[i][1].Split('~')[0];
                        maxNumber = tableDatas[i][1].Split('~')[1];
                    }

                    //测试结果
                    string res = tableDatas[i][3].Equals("1") ? "PASS" : "FAIL";

                    //编号 ， 项目名称 ， 最小值 ， 最大值 ， 实际值 ， 单位 ， 测试结果
                    int row = dataGridViewX1.Rows.Add(tableDatas[i][4], name, minNumber, maxNumber, tableDatas[i][2], unit, res);

                    //渲染颜色
                    if (res.Equals("PASS"))
                    {
                        dataGridViewX1.Rows[row].DefaultCellStyle.BackColor = Color.Green;
                    }
                    else
                    {
                        dataGridViewX1.Rows[row].DefaultCellStyle.BackColor = Color.Red;
                    }


                }

                //项目名称,可能前面会有}{符号。去除
                if (label3.Text.IndexOf("}") != -1 && label3.Text.IndexOf("{") != -1)
                {
                    label3.Text = label3.Text.Substring(2, label3.Text.Length - 2);
                }

            }));
            //清空
            SerialPortSendUtil.recivice = new List<byte>();
        }



        /// <summary>
        /// 初始化串口
        /// </summary>
        private void addPort()
        {
            string[] com = SerialPort.GetPortNames();
            this.comboBoxEx_Com.Items.Clear();
            foreach (var item in com)
            {
                this.comboBoxEx_Com.Items.Add(item);
            }

            if (this.comboBoxEx_Com.Items.Count > 0)
            {
                this.comboBoxEx_Com.Text = this.comboBoxEx_Com.Items[0].ToString();
            }
        }

        /// <summary>
        /// 刷新串口按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonX5_Click(object sender, EventArgs e)
        {
            addPort();
        }

        private void switchButton1_ValueChanged(object sender, EventArgs e)
        {
            String comboBoxExcg = comboBoxEx_Com.Text; //串口
            int comboBoxExbtl = Convert.ToInt32(comboBoxEx_btv.Text);//波特率
            if (switchButton1.Value)
            {
                //打开
                serialPort = new SerialPort(comboBoxExcg, comboBoxExbtl);
                SerialPortSendUtil serial = new SerialPortSendUtil(serialPort);
                serial.StartSerialPortMonitor(serialPort);
                serial.queryData += QueryData;
            }
            else
            {
                serialPort.Close();
            }
        }

        /// <summary>
        /// 获取数据， 然后渲染页面
        /// </summary>
        /// <param name="data"></param>
        private void QueryData(List<byte> data)
        {
            byte[] frameHeader = new byte[] { 0xA5, 0x5A };
            byte[] frameFooter = new byte[] { 0x0D, 0x0A };

            bool hasFrameHeader = false;
            bool hasFrameFooter = false;

            // 检查是否包含帧头
            for (int i = 0; i < data.Count - frameHeader.Length + 1; i++)
            {
                if (IsByteArrayEqual(data.GetRange(i, frameHeader.Length).ToArray(), frameHeader))
                {
                    hasFrameHeader = true;
                    break;
                }
            }

            // 检查是否包含帧尾
            for (int i = 0; i < data.Count - frameFooter.Length + 1; i++)
            {
                if (IsByteArrayEqual(data.GetRange(i, frameFooter.Length).ToArray(), frameFooter))
                {
                    hasFrameFooter = true;
                    break;
                }
            }

            if (hasFrameHeader && hasFrameFooter)
            {
                Console.WriteLine("数据中包含帧头 0xA5 0x5A");
                string dataStr = Encoding.GetEncoding("GB2312").GetString(data.ToArray());
                queryData(dataStr);

                //测试完自动导出
                Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(2000);
                    //导出文件
                    if (!isImport)
                    {
                        importFile();
                        isImport = true;
                    }
                });

            }
        }

        bool IsByteArrayEqual(byte[] a1, byte[] a2)
        {
            if (a1.Length != a2.Length)
            {
                return false;
            }

            for (int i = 0; i < a1.Length; i++)
            {
                if (a1[i] != a2[i])
                {
                    return false;
                }
            }

            return true;
        }

        private void dataGridViewX1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        /// <summary>
        /// 导出数据，格式CSV文件
        /// </summary>
        private void importFile()
        {

            /**
             * 1、获取表格全部行
             * 2、判断是否有值，是否是空行
             * 3、保存到集合中
             * 4、编写CSV文件格式
             * 5、插入数据 导出
             * 
             * 第一列测试的sn码
             * 第二列测试数据
             * 第三列测试结果，测试时间
             * 
             * */
            try
            {
                List<List<string>> datas = new List<List<string>>();
                //获取表格全部行
                for (int i = 0; i < dataGridViewX1.RowCount; i++)
                {
                    //2、判断是否有值，是否是空行
                    if (dataGridViewX1.Rows[i].Cells[1]?.Value != null && !String.IsNullOrWhiteSpace(dataGridViewX1.Rows[i].Cells[1]?.Value.ToString()))
                    {
                        //3、保存到集合中
                        List<string> data = new List<string>();
                        //编号
                        data.Add(dataGridViewX1.Rows[i].Cells[0]?.Value.ToString());
                        //测试项目名称
                        data.Add(dataGridViewX1.Rows[i].Cells[1]?.Value.ToString());
                        //最大值
                        data.Add(dataGridViewX1.Rows[i].Cells[2]?.Value.ToString());
                        //最小值
                        data.Add(dataGridViewX1.Rows[i].Cells[3]?.Value.ToString());
                        //实际值
                        data.Add(dataGridViewX1.Rows[i].Cells[4]?.Value.ToString());
                        //单位
                        data.Add(dataGridViewX1.Rows[i].Cells[5]?.Value.ToString());
                        //测试结果
                        data.Add(dataGridViewX1.Rows[i].Cells[6]?.Value.ToString());

                        datas.Add(data);
                    }
                }

                //开启文件流
                //获取桌面路径
                string desktopPath = AppDomain.CurrentDomain.BaseDirectory;
                //导出的路径
                string fileName = label3.Text + "_" + DateTime.Now.ToString("yyyyMMdd") + ".CSV";
                filePath = desktopPath + fileName;


                //4、编写CSV文件格式
                using (StreamWriter sw = new StreamWriter(filePath,true))
                {
                    //表头
                    sw.WriteLine("产品码:[" + result + "]");
                    //表头
                    sw.WriteLine("编号,项目名称,最大值,最小值,实际值,单位,结果");

                    //取出数据
                    for (int i = 0; i < datas.Count; i++)
                    {
                        //插入数据 导出

                        sw.WriteLine(datas[i][0] + "," + datas[i][1] + "," + datas[i][2] + "," + datas[i][3] + "," + datas[i][4] + "," + datas[i][5] + "," + datas[i][6]);
                    }

                    //测试结果，测试时间
                    string testDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    sw.WriteLine("测试结果 : "+ label6.Text+ ",测试时间 : " + testDate);

                    sw.WriteLine("");

                }
               
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }


        /// <summary>
        /// 导出数据按钮，
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonX1_Click(object sender, EventArgs e)
        {
            importFile();
            MessageBox.Show("数据导出成功，路径[" + filePath + "]");
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 写入文件
        /// </summary>
        /// <param name="msg"></param>
        private void witeLog(string msg) 
        {
            string path = base_path+"sn.txt";

            //判断是否有文件夹，没有创建
            if (!Directory.Exists(base_path))
            {
                Directory.CreateDirectory(base_path);
            }

            using (StreamWriter sw = new StreamWriter(path, true)) 
            {
                sw.Write(msg+",");

                sw.Close();
            }
        }

        /// <summary>
        /// 读取文件 ，sn码
        /// </summary>
        private string readLog() 
        {
            string path = base_path + "sn.txt";
            string sn = "";

            //判断是否有文件夹，没有创建
            if (!Directory.Exists(base_path))
            {
                Directory.CreateDirectory(base_path);
            }

            //判断是否有，没有创建
            if (!File.Exists(path))
            {
                File.CreateText(path).Close();
            }
            using (StreamReader sr = new StreamReader(path)) 
            {
                sn = sr.ReadToEnd();

                sr.Close();
            }

            return sn;
        }
        
    }
}
